package com.gbb.simple.base.nohttp;

import android.app.Activity;
import android.content.DialogInterface;

import com.gbb.resource.R;
import com.gbb.common.utils.ToastUtil;
import com.yanzhenjie.nohttp.Logger;
import com.yanzhenjie.nohttp.error.NetworkError;
import com.yanzhenjie.nohttp.error.NotFoundCacheError;
import com.yanzhenjie.nohttp.error.TimeoutError;
import com.yanzhenjie.nohttp.error.URLError;
import com.yanzhenjie.nohttp.error.UnKnownHostError;
import com.yanzhenjie.nohttp.rest.OnResponseListener;
import com.yanzhenjie.nohttp.rest.Request;
import com.yanzhenjie.nohttp.rest.Response;
import com.yanzhenjie.nohttp.rest.RestResponse;

import java.net.ProtocolException;
import java.util.Locale;

/**
 * Created in Nov 4, 2015 12:02:55 PM.
 *
 * @author Yan Zhenjie.
 */
public class HttpResponseListener<T> implements OnResponseListener<T> {

    private Activity mActivity;

    /**
     * Dialog.
     */
    private WaitDialog mWaitDialog;

    /**
     * Request.
     */
    private Request<?> mRequest;

    /**
     * 结果回调.
     */
    private HttpListener<T> callback;

    private boolean showErrow = true;

    /**
     * 默认无加载框请求
     *
     * @param activity Activity
     * @param httpCallback 回调
     */
    public HttpResponseListener(Activity activity,HttpListener<T> httpCallback){
        this(activity,null,httpCallback,false,false);
    }

    /**
     * 有加载框并且不可取消
     *
     * @param activity Activity
     * @param isLoading 是否显示加载框
     * @param httpCallback 回调
     */
    public HttpResponseListener(Activity activity,boolean isLoading,HttpListener<T> httpCallback){
        this(activity,null,httpCallback,false,isLoading);
    }

    /**
     * 可取消
     *
     * @param activity
     * @param request
     * @param httpCallback
     */
    public HttpResponseListener(Activity activity,Request<?> request,HttpListener<T> httpCallback){
        this(activity,request,httpCallback,true,true);
    }

    /**
     * @param activity context用来实例化dialog.
     * @param request 请求对象.
     * @param httpCallback 回调对象.
     * @param canCancel 是否允许用户取消请求.
     * @param isLoading 是否显示dialog.
     */
    public HttpResponseListener(Activity activity,Request<?> request,HttpListener<T> httpCallback,boolean canCancel,boolean isLoading){
        this.mActivity = activity;
        this.mRequest = request;
        if(activity != null && isLoading) {
            mWaitDialog = new WaitDialog(activity);
            mWaitDialog.setCancelable(canCancel);
            mWaitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {

                @Override
                public void onCancel(DialogInterface dialog){
                    if(mRequest != null) {
                        mRequest.cancel();
                    }
                }
            });
        }
        this.callback = httpCallback;
    }


    /**
     * 开始请求, 这里显示一个dialog.
     */
    @Override
    public void onStart(int what){
        if(mWaitDialog != null && !mActivity.isFinishing() && !mWaitDialog.isShowing()) {
            mWaitDialog.show();
        }
    }

    /**
     * 结束请求, 这里关闭dialog.
     */
    @Override
    public void onFinish(int what){
        if(mWaitDialog != null && mWaitDialog.isShowing()) {
            mWaitDialog.dismiss();
        }
    }

    /**
     * 成功回调.
     */
    @Override
    public void onSucceed(int what,Response<T> response){
        if(callback != null) {
            // 这里判断一下http响应码，这个响应码问下你们的服务端你们的状态有几种，一般是200成功。
            // w3c标准http响应码：http://www.w3school.com.cn/tags/html_ref_httpmessages.asp

            int code = response.responseCode();
            if(code == 200 || code == 304) {
                // 如果使用http标准的304重定向到缓存的话，还要判断下304状态码。
                Logger.i(response.get());
                callback.onSucceed(what,response);
            } else {
                // 这里可以传一个你的自定义异常。
                Response<T> error = new RestResponse<>(response.request(),response.isFromCache(),response.getHeaders(),null,response.getNetworkMillis(),new ServerCodeException("返回码错误：" + code));
                onFailed(what,error); // 去让错误的回调处理。
            }
        }
    }


    /**
     * 失败回调.
     */
    @Override
    public void onFailed(int what,Response<T> response){
        if(callback != null) {
            callback.onFailed(what,response);
        }

        if(!showErrow) {
            return;
        }

        Exception exception = response.getException();
        if(exception instanceof NetworkError) {// 网络不好
            ToastUtil.showToast(R.string.error_please_check_network);
        } else if(exception instanceof TimeoutError) {// 请求超时
            ToastUtil.showToast(R.string.error_timeout);
        } else if(exception instanceof UnKnownHostError) {// 找不到服务器
            ToastUtil.showToast(R.string.error_not_found_server);
        } else if(exception instanceof URLError) {// URL是错的
            ToastUtil.showToast(R.string.error_url_error);
        } else if(exception instanceof NotFoundCacheError) {
            // 这个异常只会在仅仅查找缓存时没有找到缓存时返回
            ToastUtil.showToast(R.string.error_not_found_cache);
        } else if(exception instanceof ProtocolException) {
            ToastUtil.showToast(R.string.error_system_unsupport_method);
        } else {
            // ToastUtil.showToast(R.string.error_unknow);
        }
        Logger.e(String.format(Locale.getDefault(),"状态码:%d\n错误信息:%s",response.responseCode(),exception.getMessage()));
    }

    public HttpResponseListener<T> setMessage(CharSequence message){
        if(mWaitDialog != null) {
            mWaitDialog.setMessage(message);
        }
        return this;
    }

    public HttpResponseListener<T> setMessage(int stringRes){
        if(mWaitDialog != null && mActivity != null) {
            mWaitDialog.setMessage(mActivity.getString(stringRes));
        }
        return this;
    }

    public HttpResponseListener<T> showError(boolean showError){
        this.showErrow = showError;
        return this;
    }
}
